﻿using AutoMapper;
using Common.Enum;
using Entity.WMS.DTO.WarehouseStocktaking;
using Entity.WMS.Entity;
using Entity.WMS.View.WarehouseStocktaking;
using FrameWork.DataContext;
using FrameWork.DataHelper;
using FrameWork.Request;
using Microsoft.EntityFrameworkCore;

namespace Service.WMS
{
    public class WarehouseStocktakingService
    {
        /**
         * 数据库
         */
        private readonly DataContext _context;

        /**
         * 自动映射
         */
        private readonly IMapper _mapper;

        /**
         * 构造注入
         */
        public WarehouseStocktakingService(DataContext context, IMapper mapper)
        {
            _context = context;
            _mapper = mapper;
        }

        /**
         * 获取库存盘点单列表
         */
        public async Task<RequestResponseModel<PageResult<WarehouseStocktakingView>>> GetWarehouseStocktakingList(WarehouseStocktakingSearchDTO warehouseStocktakingSearchDTO)
        {
            //筛选
            var query = _context.warehouseStocktakingView
                .WhereIF(a => a.Code.Contains(warehouseStocktakingSearchDTO.Code), !string.IsNullOrEmpty(warehouseStocktakingSearchDTO.Code))
                .WhereIF(a => a.ExamStatus == warehouseStocktakingSearchDTO.ExamStatus, warehouseStocktakingSearchDTO.ExamStatus != null)
                ;

            //返回列表
            var warehouseStocktakingList = await query
                .OrderBy(a => a.CreateTime)
                .Page(warehouseStocktakingSearchDTO.CurrentPage, warehouseStocktakingSearchDTO.PageSize)
                .ToListAsync();

            //计算总数
            var pageCount = await query.CountAsync();

            //返回数据
            var pageResult = new PageResult<WarehouseStocktakingView>(warehouseStocktakingList, pageCount);
            return RequestResponse.CreateResponse(200, "查询成功", pageResult);
        }

        /**
         * 获取库存盘点单子单列表
         */
        public async Task<RequestResponseModel<PageResult<WarehouseStocktakingItemView>>> GetWarehouseStocktakingItemList(WarehouseStocktakingItemSearchDTO warehouseStocktakingItemSearchDTO)
        {
            //筛选
            var query = _context.WarehouseStocktakingItemView
                .Where(a => a.WarehouseStocktakingId == warehouseStocktakingItemSearchDTO.Id)
                ;

            //返回列表
            var warehouseStocktakingItemList = await query
                .Page(warehouseStocktakingItemSearchDTO.CurrentPage, warehouseStocktakingItemSearchDTO.PageSize)
                .ToListAsync();

            //总数据量
            var pageCount = await query.CountAsync();

            //返回数据
            var pageResult = new PageResult<WarehouseStocktakingItemView>(warehouseStocktakingItemList, pageCount);
            return RequestResponse.CreateResponse(200, "查询成功", pageResult);
        }

        /**
         * 新增库存盘点单
         */
        public async Task<RequestResponseModel<string>> AddWarehouseStocktaking(WarehouseStocktakingAddDTO warehouseStocktakingAddDTO)
        {
            //处理主单单据
            var warehouseStocktaking = _mapper.Map<WarehouseStocktakingModel>(warehouseStocktakingAddDTO);
            warehouseStocktaking.Id = Guid.NewGuid().ToString();
            warehouseStocktaking.CreateTime = DateTime.Now;
            warehouseStocktaking.ExamStatus = StateEnum.ExamStatus.待审核;

            //处理子单单据
            var warehouseStocktakingItem = _mapper.Map<List<WarehouseStocktakingItemModel>>(warehouseStocktakingAddDTO.Items);
            foreach (var item in warehouseStocktakingItem)
            {
                item.Id = Guid.NewGuid().ToString();
                item.WarehouseStocktakingId = warehouseStocktaking.Id;
            }

            //修改并保存数据库
            _context.WarehouseStocktaking.Add(warehouseStocktaking);
            _context.WarehouseStocktakingItem.AddRange(warehouseStocktakingItem);
            await _context.SaveChangesAsync();
            return RequestResponse.CreateResponse(200, "新增成功", warehouseStocktaking.Id);
        }

        /**
         * 库存盘点单 - 审核通过
         */
        public async Task<RequestResponseModel<string>> PassWarehouseStocktaking(string Id)
        {
            //校验id
            var query = await Valid.ValidId(_context.WarehouseStocktaking, Id);
            if (query == null)
            {
                return RequestResponse.CreateResponse(400, "Id无效", Id);
            }

            //校验状态
            if (query.ExamStatus != StateEnum.ExamStatus.待审核)
            {
                return RequestResponse.CreateResponse(400, "只有待审核的单据才可以审核通过", Id);
            }

            //修改主单状态，并修改数据库
            query.ExamStatus = StateEnum.ExamStatus.审核通过;
            _context.WarehouseStocktaking.Update(query);

            //查找该单据的子单
            var warehouseStocktakingItem = await _context.WarehouseStocktakingItemView
                .Where(a => a.WarehouseStocktakingId == Id)
                .ToListAsync();

            //整合盘点单子单数据
            var goodsIdList = warehouseStocktakingItem.Select(a => a.GoodsId).ToList();
            var warehouseIdList = warehouseStocktakingItem.Select(a => a.WarehouseId).ToList();
            var warehousePositionIdList = warehouseStocktakingItem.Select(a => a.WarehousePositionId).ToList();
            var batchNumberList = warehouseStocktakingItem.Select(a => a.BatchNumber).ToList();

            //处理结存主单
            var warehouseBalanceList = await _context.WarehouseBalance
                .Where(a => goodsIdList.Contains(a.GoodsId))
                .ToListAsync()
                ;

            //处理仓库库存单
            var warehouseInventoryList = await _context.WarehouseInventory
                .Where(a => goodsIdList.Contains(a.GoodsId))
                .Where(a => warehouseIdList.Contains(a.WarehouseId))
                .Where(a => warehousePositionIdList.Contains(a.WarehousePositionId))
                .Where(a => batchNumberList.Contains(a.BatchNumber))
                .ToListAsync();

            //处理每一个盘点子单
            foreach (var item in warehouseStocktakingItem)
            {
                //处理结存主单
                var balance = warehouseBalanceList.Find(a => a.GoodsId == item.GoodsId);
                if (balance == null)
                {
                    return RequestResponse.CreateResponse(400, "物料编码：" + item.GoodsCode + "；物料名称：" + item.GoodsName + "：库存结存中无该物料", Id);
                }
                else
                {
                    if (item.Number_Stocktaking + balance.Number_End < 0)
                    {
                        return RequestResponse.CreateResponse(400, "物料编码：" + item.GoodsCode + "；物料名称：" + item.GoodsName + "：库存结存该物料数量不足", Id);
                    }
                    balance.Number_End += item.Number_Stocktaking;
                    balance.Number_Begin = balance.Number_End;
                    balance.Number_Out = 0;
                    balance.Number_In = 0;
                    _context.WarehouseBalance.Update(balance);
                }

                //处理结存子单
                var balanceItem = _mapper.Map<WarehouseBalanceItemModel>(item);
                balanceItem.Id = Guid.NewGuid().ToString();
                balanceItem.WarehouseBalanceId = balance.Id;
                balanceItem.Type = StateEnum.WarehouseType.库存盘点;
                if (item.Number_Stocktaking > 0)
                {
                    balanceItem.Number_Out = item.Number_Stocktaking;
                    balanceItem.Number_In = 0;
                }
                else
                {
                    balanceItem.Number_In = Math.Abs(item.Number_Stocktaking);
                    balanceItem.Number_Out = 0;
                }
                balanceItem.Number_Real = balance.Number_End;
                balanceItem.CurrentPeriod = true;
                balanceItem.CreateTime = DateTime.Now;
                _context.WarehouseBalanceItem.Add(balanceItem);

                //处理仓库库存单
                var warehouseInventory = warehouseInventoryList.Find(a => a.GoodsId == item.GoodsId && a.WarehouseId == item.WarehouseId && a.WarehousePositionId == item.WarehousePositionId && a.BatchNumber == item.BatchNumber);
                if (warehouseInventory == null)
                {
                    return RequestResponse.CreateResponse(400, "物料编码：" + item.GoodsCode + "；物料名称：" + item.GoodsName + "：仓库库存中无该物料", Id);
                }
                else
                {
                    if (item.Number_Stocktaking + balance.Number_End < 0)
                    {
                        return RequestResponse.CreateResponse(400, "物料编码：" + item.GoodsCode + "；物料名称：" + item.GoodsName + "：仓库库存中该物料数量不足", Id);
                    }
                    warehouseInventory.Number_Real += item.Number_Stocktaking;
                    _context.WarehouseInventory.Update(warehouseInventory);
                    await _context.SaveChangesAsync();
                }
            }

            //处理结存子单
            var warehouseBalanceItemList = await _context.WarehouseBalanceItem
                .Where(a => goodsIdList.Contains(a.GoodsId))
                .ToListAsync()
                ;
            foreach (var item in warehouseBalanceItemList)
            {
                item.CurrentPeriod = false;
            }
            _context.WarehouseBalanceItem.UpdateRange(warehouseBalanceItemList);

            //保存数据库
            await _context.SaveChangesAsync();
            return RequestResponse.CreateResponse(200, "审核通过成功", Id);
        }

        /**
         * 删除库存盘点单
         */
        public async Task<RequestResponseModel<string>> DeleteWarehouseStocktaking(string Id)
        {
            //校验id有效性
            var query = await Valid.ValidId(_context.WarehouseStocktaking, Id);
            if (query == null)
            {
                return RequestResponse.CreateResponse(400, "id无效", Id);
            }

            //已审核的单据无法删除
            if (query.ExamStatus == StateEnum.ExamStatus.审核通过)
            {
                return RequestResponse.CreateResponse(400, "审核通过的单据无法删除", Id);
            }

            //查找该id下的子单
            var warehouseStocktakingItemList = _context.WarehouseStocktakingItem
                .Where(a => a.Id.Equals(Id));

            //操作数据库并保存
            _context.WarehouseStocktaking.Remove(query);
            _context.WarehouseStocktakingItem.RemoveRange(warehouseStocktakingItemList);
            await _context.SaveChangesAsync();
            return RequestResponse.CreateResponse(200, "删除成功", Id);
        }



        /**
         * 库存盘点单 - 审核不通过
         */
        public async Task<RequestResponseModel<string>> UnPassWarehouseStocktaking(string Id)
        {
            //校验id
            var query = await Valid.ValidId(_context.WarehouseStocktaking, Id);
            if (query == null)
            {
                return RequestResponse.CreateResponse(400, "Id无效", Id);
            }

            //校验状态
            if (query.ExamStatus != StateEnum.ExamStatus.待审核)
            {
                return RequestResponse.CreateResponse(400, "只有待审核的单据才可以审核不通过", Id);
            }

            //修改数据
            query.ExamStatus = StateEnum.ExamStatus.审核不通过;

            //修改并保存数据库
            _context.WarehouseStocktaking.Update(query);
            await _context.SaveChangesAsync();
            return RequestResponse.CreateResponse(200, "审核不通过成功", Id);
        }

        /**
         * 库存盘点单 - 反审核
         */
        public async Task<RequestResponseModel<string>> CancelPassWarehouseStocktaking(string Id)
        {
            //校验id
            var query = await Valid.ValidId(_context.WarehouseStocktaking, Id);
            if (query == null)
            {
                return RequestResponse.CreateResponse(400, "Id无效", Id);
            }

            //校验状态
            if (query.ExamStatus != StateEnum.ExamStatus.审核不通过)
            {
                return RequestResponse.CreateResponse(400, "只有审核不通过的单据才可以反审核", Id);
            }

            //修改数据
            query.ExamStatus = StateEnum.ExamStatus.待审核;

            //修改并保存数据库
            _context.WarehouseStocktaking.Update(query);
            await _context.SaveChangesAsync();
            return RequestResponse.CreateResponse(200, "反审核成功", Id);
        }
    }
}
